package com.franklin.ideaplugin.maphelper.resolver.impl.map;

import cn.hutool.core.collection.CollectionUtil;
import com.franklin.ideaplugin.api.beans.declaration.IDeclaration;
import com.franklin.ideaplugin.api.beans.variable.IVariable;
import com.franklin.ideaplugin.api.utils.psi.PsiClassUtils;
import com.franklin.ideaplugin.api.utils.psi.PsiExpressionUtils;
import com.franklin.ideaplugin.api.utils.psi.PsiTreeUtils;
import com.franklin.ideaplugin.maphelper.beans.colmember.IColMember;
import com.franklin.ideaplugin.maphelper.col.declaration.IColDeclaration;
import com.franklin.ideaplugin.maphelper.col.operation.ColOperationFactory;
import com.franklin.ideaplugin.maphelper.col.method.IColQueryMethod;
import com.franklin.ideaplugin.maphelper.utils.PsiColUtils;
import com.franklin.ideaplugin.maphelper.utils.PsiMapUtils;
import com.google.common.collect.Sets;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;

import java.util.Collection;
import java.util.Objects;
import java.util.Set;

/**
 * map的内部map
 *
 * @author Ye Junhui
 * @since 2024/3/8
 */
public class InnerMapMapMethodCallExpressionMemberResolver implements IMapMemberResolver {

    public final static InnerMapMapMethodCallExpressionMemberResolver INSTANCE = new InnerMapMapMethodCallExpressionMemberResolver();

    @Override
    public boolean supports(IColDeclaration colDeclaration) {
        IDeclaration declaration = colDeclaration.getDeclaration();
        IVariable variable = declaration.getVariable();
        if (Objects.isNull(variable)){
            return false;
        }
        PsiType psiType = variable.getPsiType();
        if (!PsiClassType.class.isInstance(psiType)){
            return false;
        }
        PsiClassType psiClassType = (PsiClassType) psiType;
        PsiClass psiClass = psiClassType.resolve();
        if (!PsiClassUtils.isJavaMapClass(psiClass)){
            return false;
        }

        //操作
        IColQueryMethod colQueryMethod = getColQueryMethod(colDeclaration);

        return Objects.nonNull(colQueryMethod);
    }

    @Override
    public Collection<IColMember> resolveColMembers(PsiElement psiExpression, IColDeclaration colDeclaration) {
        //结果
        Set<IColMember> result = Sets.newLinkedHashSet();

        //当前代码块
        Collection<IColMember> currentMembers = MapNewExpressionMemberResolver.INSTANCE.resolveColMembers(psiExpression, colDeclaration);
        CollectionUtil.addAll(result,currentMembers);

        //寻找父map
        PsiElement psiElement = colDeclaration.getDeclaration().getPsiElement();
        //类型强转表达式
        //父map get子map表达式
        PsiMethodCallExpression parentMethodCallExpression = PsiTreeUtils.findLastElement(psiElement, PsiMethodCallExpression.class);
        PsiReferenceExpression parentReferenceExpression = PsiTreeUtil.findChildOfType(parentMethodCallExpression, PsiReferenceExpression.class);

        //父map 调用方法
        PsiIdentifier psiIdentifier = PsiTreeUtil.findChildOfType(parentReferenceExpression, PsiIdentifier.class);
        if (Objects.isNull(psiIdentifier)){
            return result;
        }

        //查询方法
        IColQueryMethod colQueryMethod = getColQueryMethod(colDeclaration);
        if (Objects.isNull(colQueryMethod)){
            return result;
        }

        //父map变量
        PsiReferenceExpression realParentReferenceExpression = PsiTreeUtils.findLastChild(parentReferenceExpression, PsiReferenceExpression.class);
        //父map定义
        IColDeclaration parentMapDeclaration = PsiMapUtils.findMapExpressionDeclaration(realParentReferenceExpression);
        if (Objects.isNull(parentMapDeclaration)){
            return result;
        }

        //寻找父map get子map的key
        PsiExpressionList psiExpressionList = PsiTreeUtil.findChildOfType(parentMethodCallExpression, PsiExpressionList.class);
        if (Objects.isNull(psiExpressionList)){
            return result;
        }

        //key索引
        int queryTargetIndex = colQueryMethod.getQueryTargetIndex();
        if (queryTargetIndex < 0){
            return result;
        }

        //索引越界，直接返回
        if (psiExpressionList.getExpressionCount() <= queryTargetIndex){
            return result;
        }

        //根据索引获取key
        PsiExpression keyExpression = psiExpressionList.getExpressions()[queryTargetIndex];

        //目标key
        String targetKeyText = keyExpression.getText();

        //寻找父map的成员
        MapMemberResolverFactory mapMemberResolverFactory = getColMemberResolverFactory();
        Collection<IColMember> parentMembers = mapMemberResolverFactory.resolveExpression(parentReferenceExpression, parentMapDeclaration);
        if (CollectionUtil.isEmpty(parentMembers)){
            return result;
        }

        //匹配key
        for (IColMember parentMember : parentMembers) {
            String keyText = parentMember.getKeyText();
            if (keyText.equals(targetKeyText)){
                //匹配成功
                Collection<IColMember> parentChildren = parentMember.getChildren(mapMemberResolverFactory);
                CollectionUtil.addAll(result,parentChildren);
            }
        }
        return result;
    }

    /**
     * 获取查询操作
     * @param colDeclaration
     * @return
     */
    private IColQueryMethod getColQueryMethod(IColDeclaration colDeclaration){
        return PsiColUtils.findColQueryMethod(colDeclaration, ColOperationFactory.MAP_READ_WRITE_OPERATIONS);
    }
}
